package vp.util;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import nc.bs.pub.formulaparse.FormulaParse;
import nc.uap.cpb.log.CpLogger;
import nc.uap.lfw.core.AppInteractionUtil;
import nc.uap.lfw.core.base.ExtAttribute;
import nc.uap.lfw.core.comp.FormComp;
import nc.uap.lfw.core.comp.FormElement;
import nc.uap.lfw.core.comp.GridColumn;
import nc.uap.lfw.core.comp.GridColumnGroup;
import nc.uap.lfw.core.comp.GridComp;
import nc.uap.lfw.core.comp.IDataBinding;
import nc.uap.lfw.core.comp.IGridColumn;
import nc.uap.lfw.core.comp.WebComponent;
import nc.uap.lfw.core.ctx.AppLifeCycleContext;
import nc.uap.lfw.core.ctx.ViewContext;
import nc.uap.lfw.core.data.Dataset;
import nc.uap.lfw.core.data.EmptyRow;
import nc.uap.lfw.core.data.Field;
import nc.uap.lfw.core.data.FieldSet;
import nc.uap.lfw.core.data.MDField;
import nc.uap.lfw.core.data.Row;
import nc.uap.lfw.core.data.RowData;
import nc.uap.lfw.core.data.UnmodifiableMdField;
import nc.uap.lfw.core.exception.LfwRuntimeException;
import nc.uap.lfw.core.exception.LfwValidateException;
import nc.uap.lfw.core.formular.LfwFormulaParser;
import nc.uap.lfw.core.log.LfwLogger;
import nc.uap.lfw.core.page.LfwView;
import nc.uap.lfw.core.page.ViewComponents;
import nc.uap.lfw.core.uif.delegator.FieldValidator;
import nc.uap.lfw.core.uif.delegator.IDataValidator;
import nc.uap.lfw.jsp.uimeta.UIMeta;
import nc.uap.lfw.util.LanguageUtil;
import nc.vo.ml.AbstractNCLangRes;
import nc.vo.ml.MultiLangContext;
import nc.vo.ml.NCLangRes4VoTransl;
import nc.vo.pub.formulaset.VarryVO;
import nc.vo.pub.lang.UFDouble;
import org.apache.commons.lang.StringUtils;
import uap.lfw.core.language.LfwLanguageVO;
import uap.lfw.core.ml.LfwResBundle;

public class IDataValidatorUtil
  implements IDataValidator
{
  private static final String ErrorFlag = "$Error";
  private static final String MessageFlag = "$Message";
  private static final String ConfirmFlag = "$Confirm";
  
  public IDataValidatorUtil(){
	  
  }
  
  private void validate(Dataset ds)
  {
    UIMeta uimeta = AppLifeCycleContext.current().getViewContext().getUIMeta();
    LfwView widget = AppLifeCycleContext.current().getViewContext().getView();
    ViewComponents vc = widget.getViewComponents();
    if (vc != null)
    {
      WebComponent[] wcs = vc.getComponents();
      if ((wcs != null) && (wcs.length > 0))
      {
        List<WebComponent> comps = new ArrayList();
        for (WebComponent wc : wcs) {
          if (uimeta.findChildById(wc.getId()) != null) {
            if (((wc instanceof FormComp)) && (ds.getId().equals(((FormComp)wc).getDataset()))) {
              comps.add(0, wc);
            } else if (((wc instanceof GridComp)) && (ds.getId().equals(((GridComp)wc).getDataset()))) {
              comps.add(wc);
            }
          }
        }
        for (WebComponent wc : comps) {
          if ((wc instanceof FormComp)) {
            validate(ds, (FormComp)wc);
          } else if ((wc instanceof GridComp)) {
            validate(ds, (GridComp)wc);
          }
        }
      }
    }
  }
  
  public void validate(Dataset ds, LfwView widget)
  {
    if ((widget == null) || (widget.getId() == null))
    {
      validate(ds);
    }
    else
    {
      WebComponent[] comps = widget.getViewComponents().getComponents();
      if ((comps != null) && (comps.length > 0)) {
        for (WebComponent comp : comps) {
          if ((comp instanceof IDataBinding))
          {
            IDataBinding dbcomp = (IDataBinding)comp;
            if (ds.getId().equals(dbcomp.getDataset())) {
              validate(ds, dbcomp);
            }
          }
        }
      }
    }
    showValidateInOldStyle(ds);
  }
  
  private void validate(Dataset ds, IDataBinding compment)
  {
    if ((compment instanceof FormComp)) {
      validate(ds, (FormComp)compment);
    } else if ((compment instanceof GridComp)) {
      validate(ds, (GridComp)compment);
    }
  }
  
  public void validate(Dataset ds, FormComp fc)
  {
    FieldSet fs;
    Field field;
    if (fc != null)
    {
      fc.hideErrorMsg();
      List<FormElement> elements = fc.getElementList();
      if ((elements != null) && (elements.size() > 0))
      {
        fs = ds.getFieldSet();
        field = null;
        for (FormElement fe : elements)
        {
          field = fs.getField(fe.getField());
          if ((field != null) && (field.isNullAble()) && (!fe.isNullAble())) {
            if ((field instanceof UnmodifiableMdField))
            {
              MDField f = ((UnmodifiableMdField)field).getMDField();
              f.setNullAble(fe.isNullAble());
              ds.getFieldSet().updateField(f.getId(), f);
            }
            else
            {
              field.setNullAble(fe.isNullAble());
            }
          }
        }
      }
    }
    Map<String, Object> validatorMap = validator(ds);
    if (validatorMap == null) {
      return;
    }
    validatorMap = dealValidator(validatorMap, ds);
    
    Map<String, String> error_fields_map = (Map)validatorMap.get("error_fields_map");
    if ((error_fields_map != null) && (!error_fields_map.isEmpty()))
    {
      UIMeta uimeta = AppLifeCycleContext.current().getViewContext().getUIMeta();
      LfwView widget = AppLifeCycleContext.current().getViewContext().getView();
      
      boolean isExist = (fc != null) && (uimeta.findChildById(fc.getId()) != null);
      if (!isExist)
      {
        List<FormElement> eles = fc != null ? fc.getElementList() : null;
        int size = eles != null ? eles.size() : 0;
        for (int i = 0; i < size; i++) {
          if (eles.get(i) != null)
          {
            isExist = uimeta.findChildById(((FormElement)eles.get(i)).getId()) != null;
            if (isExist) {
              break;
            }
          }
        }
      }
      if ((isExist) && (ds.getId().equals(fc.getDataset())))
      {
        int index = 1;
        StringBuffer allErrorMsg = new StringBuffer(FieldValidator.getValidatorMsg(FieldValidator.ValidatorType.saveFailure.ordinal()));
        


        Map<Integer, List<Field>> type_fields_map = (Map)validatorMap.get("type_fields_map");
        if ((type_fields_map != null) && (!type_fields_map.isEmpty()))
        {
          List<Field> list = null;
          FieldValidator.ValidatorType[] types = FieldValidator.ValidatorType.values();
          for (FieldValidator.ValidatorType type : types)
          {
            list = (List)type_fields_map.get(Integer.valueOf(type.ordinal()));
            if ((list != null) && (list.size() > 0)) {
              index = getFieldErrorMsgByErrorType(allErrorMsg, list, fc, index, FieldValidator.getValidatorMsg(type.ordinal()) + NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000000"));
            }
          }
        }
        Map<String, List<Field>> formular_fields_map = (Map)validatorMap.get("formular_fields_map");
        if ((formular_fields_map != null) && (!formular_fields_map.isEmpty()))
        {
          List<Field> list = null;
          String key = null;
          Iterator<String> keys = formular_fields_map.keySet().iterator();
          while (keys.hasNext())
          {
            key = (String)keys.next();
            list = (List)formular_fields_map.get(key);
            if ((list != null) && (list.size() > 0)) {
              index = getFieldErrorMsgByErrorType(allErrorMsg, list, fc, index, key + NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000000"));
            }
          }
        }
        if (index > 1)
        {
          LfwValidateException exception = new LfwValidateException(allErrorMsg.toString());
          exception.setViewId(widget.getId());
          exception.addComponentId(fc.getId());
          exception.setElementMap(error_fields_map);
          
          CpLogger.error("validate failed,widget:" + widget.getId() + ",comp:" + fc.getId() + ",info:" + allErrorMsg.toString(), exception);
          
          throw exception;
        }
      }
    }
    else
    {
      Map<String, Map<String, String>> formularMaps = (Map)validatorMap.get("formularMsgMap");
      
      Map<String, String> formularMessageMap = (Map)formularMaps.get("$Message");
      if (!formularMessageMap.isEmpty())
      {
        Iterator<String> keys = formularMessageMap.keySet().iterator();
        while (keys.hasNext())
        {
          String key = (String)keys.next();
          
          String message = (String)formularMessageMap.get(key);
          AppInteractionUtil.showMessageDialog(message);
        }
      }
      Map<String, String> formularConfirmMap = (Map)formularMaps.get("$Confirm");
      if (!formularConfirmMap.isEmpty())
      {
        Iterator<String> keys = formularConfirmMap.keySet().iterator();
        while (keys.hasNext())
        {
          String key = (String)keys.next();
          String message = (String)formularConfirmMap.get(key);
          
          AppInteractionUtil.showConfirmDialog(key, LfwResBundle.getInstance().getStrByID("webrt", "DefaultDataValidator-000000"), message, "");
          if (!AppInteractionUtil.getConfirmDialogResult(key).booleanValue()) {
            return;
          }
        }
      }
    }
  }
  
  private int getFieldErrorMsgByErrorType(StringBuffer allErrorMsg, List<Field> list, FormComp fc, int index, String titleError)
  {
    List<FormElement> fes = fc.getElementList();
    if ((fes != null) && (fes.size() > 0))
    {
      boolean isNeedToShowError = false;
      FormElement[] formElements = new FormElement[fes.size()];
      int size = list.size();
      for (int i = 0; i < size; i++)
      {
        Field f = (Field)list.get(i);
        
        String id = f.getId();
        int fieldIndex = fc.idToIndex(id);
        if ((fieldIndex == -1) && (f.getSourceField() != null))
        {
          id = f.getSourceField();
          fieldIndex = fc.idToIndex(id);
        }
        if ((fieldIndex != -1) && (fc.getElementById(id).isVisible()))
        {
          formElements[fieldIndex] = ((FormElement)fes.get(fieldIndex));
          isNeedToShowError = true;
        }
      }
      if (isNeedToShowError)
      {
        index++;
        allErrorMsg.append(titleError);
        boolean temp = false;
        for (int i = 0; i < formElements.length; i++) {
          if (formElements[i] != null)
          {
            String text = LanguageUtil.translate(formElements[i].getI18nName(), formElements[i].getText(), formElements[i].getLangDir());
            allErrorMsg.append((temp ? NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000001") : "") + NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000002") + text + NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000003"));
            temp = true;
          }
        }
        allErrorMsg.append(";");
      }
    }
    return index;
  }
  
  public void validate(Dataset ds, GridComp gc)
  {
    FieldSet fs;
    Field field;
    if (gc != null)
    {
      gc.hideErrorMsg();
      List<IGridColumn> columns = gc.getColumnList();
      if ((columns != null) && (columns.size() > 0))
      {
        fs = ds.getFieldSet();
        field = null;
        for (IGridColumn colum : columns) {
          if ((colum instanceof GridColumn))
          {
            field = fs.getField(((GridColumn)colum).getField());
            if ((field != null) && (field.isNullAble())) {
              if ((field instanceof UnmodifiableMdField))
              {
                MDField f = ((UnmodifiableMdField)field).getMDField();
                f.setNullAble(((GridColumn)colum).isNullAble());
                ds.getFieldSet().updateField(f.getId(), f);
              }
              else
              {
                field.setNullAble(((GridColumn)colum).isNullAble());
              }
            }
          }
        }
      }
    }
    Map<String, Object> validatorMap = validator(ds, true);
    if (validatorMap == null) {
      return;
    }
    validatorMap = dealValidator(validatorMap, ds);
    
    Map<String, String> error_fields_map = (Map)validatorMap.get("error_fields_map");
    if ((error_fields_map != null) && (!error_fields_map.isEmpty()))
    {
      UIMeta uimeta = AppLifeCycleContext.current().getViewContext().getUIMeta();
      LfwView widget = AppLifeCycleContext.current().getViewContext().getView();
      if ((gc != null) && (uimeta.findChildById(gc.getId()) != null) && (ds.getId().equals(gc.getDataset())))
      {
        int index = 1;
        StringBuffer allErrorMsg = new StringBuffer(FieldValidator.getValidatorMsg(FieldValidator.ValidatorType.saveFailure.ordinal()));
        


        Map<Integer, List<Field>> type_fields_map = (Map)validatorMap.get("type_fields_map");
        if ((type_fields_map != null) && (!type_fields_map.isEmpty()))
        {
          List<Field> list = null;
          FieldValidator.ValidatorType[] types = FieldValidator.ValidatorType.values();
          for (FieldValidator.ValidatorType type : types)
          {
            list = (List)type_fields_map.get(Integer.valueOf(type.ordinal()));
            if ((list != null) && (list.size() > 0)) {
              index = getFieldErrorMsgByErrorType(allErrorMsg, list, gc, index, FieldValidator.getValidatorMsg(type.ordinal()) + NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000000"));
            }
          }
        }
        Map<String, List<Field>> formular_fields_map = (Map)validatorMap.get("formular_fields_map");
        if ((formular_fields_map != null) && (!formular_fields_map.isEmpty()))
        {
          List<Field> list = null;
          String key = null;
          Iterator<String> keys = formular_fields_map.keySet().iterator();
          while (keys.hasNext())
          {
            key = (String)keys.next();
            list = (List)formular_fields_map.get(key);
            if ((list != null) && (list.size() > 0)) {
              index = getFieldErrorMsgByErrorType(allErrorMsg, list, gc, index, key + NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000000"));
            }
          }
        }
        if (index > 1)
        {
          LfwValidateException exception = new LfwValidateException(allErrorMsg.toString());
          exception.setViewId(widget.getId());
          exception.addComponentId(gc.getId());
          exception.setElementMap(error_fields_map);
          throw exception;
        }
      }
    }
    else
    {
      Map<String, Map<String, String>> formularMaps = (Map)validatorMap.get("formularMsgMap");
      
      Map<String, String> formularMessageMap = (Map)formularMaps.get("$Message");
      if (!formularMessageMap.isEmpty())
      {
        Iterator<String> keys = formularMessageMap.keySet().iterator();
        while (keys.hasNext())
        {
          String key = (String)keys.next();
          
          String message = (String)formularMessageMap.get(key);
          AppInteractionUtil.showMessageDialog(message);
        }
      }
      Map<String, String> formularConfirmMap = (Map)formularMaps.get("$Confirm");
      if (!formularConfirmMap.isEmpty())
      {
        Iterator<String> keys = formularConfirmMap.keySet().iterator();
        while (keys.hasNext())
        {
          String key = (String)keys.next();
          String message = (String)formularConfirmMap.get(key);
          
          AppInteractionUtil.showConfirmDialog(key, LfwResBundle.getInstance().getStrByID("webrt", "DefaultDataValidator-000000"), message, "");
          if (!AppInteractionUtil.getConfirmDialogResult(key).booleanValue()) {
            throw new LfwRuntimeException(message);
          }
        }
      }
    }
  }
  
  private int getFieldErrorMsgByErrorType(StringBuffer allErrorMsg, List<Field> list, GridComp gc, int index, String titleError)
  {
    List<IGridColumn> fes = gc.getAllColumnList();
    if ((fes != null) && (fes.size() > 0))
    {
      boolean isNeedToShowError = false;
      IGridColumn[] gridColumns = new IGridColumn[fes.size()];
      int size = list.size();
      for (int i = 0; i < size; i++)
      {
        Field f = (Field)list.get(i);
        IGridColumn col = null;
        if (f.getField() != null) {
          col = gc.getColumnByField(f.getField());
        } else if (f.getId() != null) {
          col = gc.getColumnByField(f.getId());
        }
        if ((col != null) && (col.isVisible()))
        {
          for (int k = 0; k < fes.size(); k++) {
            if (col.getId().equals(((IGridColumn)fes.get(k)).getId()))
            {
              gridColumns[k] = col;
              break;
            }
          }
          isNeedToShowError = true;
        }
      }
      if (isNeedToShowError)
      {
        index++;
        allErrorMsg.append(titleError);
        boolean temp = false;
        for (int i = 0; i < gridColumns.length; i++) {
          if (gridColumns[i] != null)
          {
            String text = null;
            if ((gridColumns[i] instanceof GridColumn)) {
              text = LanguageUtil.translate(((GridColumn)gridColumns[i]).getI18nName(), ((GridColumn)gridColumns[i]).getText(), ((GridColumn)gridColumns[i]).getLangDir());
            } else if ((gridColumns[i] instanceof GridColumnGroup)) {
              text = LanguageUtil.translate(((GridColumnGroup)gridColumns[i]).getI18nName(), ((GridColumnGroup)gridColumns[i]).getText(), ((GridColumnGroup)gridColumns[i]).getLangDir());
            }
            allErrorMsg.append((temp ? NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000001") : "") + NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000002") + text + NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000003"));
            temp = true;
          }
        }
      }
    }
    return index;
  }
  
  public void showValidateInOldStyle(Dataset ds)
  {
    Map<String, Object> validatorMap = validator(ds);
    if (validatorMap == null) {
      return;
    }
    validatorMap = dealValidator(validatorMap, ds);
    
    Map<String, String> error_fields_map = (Map)validatorMap.get("error_fields_map");
    if ((error_fields_map != null) && (!error_fields_map.isEmpty()))
    {
      int index = 1;
      StringBuffer allErrorMsg = new StringBuffer(FieldValidator.getValidatorMsg(FieldValidator.ValidatorType.saveFailure.ordinal()));
      


      Map<Integer, List<Field>> type_fields_map = (Map)validatorMap.get("type_fields_map");
      if ((type_fields_map != null) && (!type_fields_map.isEmpty()))
      {
        List<Field> list = null;
        FieldValidator.ValidatorType[] types = FieldValidator.ValidatorType.values();
        for (FieldValidator.ValidatorType type : types)
        {
          list = (List)type_fields_map.get(Integer.valueOf(type.ordinal()));
          if ((list != null) && (list.size() > 0)) {
            index = getFieldErrorMsgByErrorType(allErrorMsg, list, index, FieldValidator.getValidatorMsg(type.ordinal()) + NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000000"));
          }
        }
      }
      Map<String, List<Field>> formular_fields_map = (Map)validatorMap.get("formular_fields_map");
      if ((formular_fields_map != null) && (!formular_fields_map.isEmpty()))
      {
        List<Field> list = null;
        String key = null;
        Iterator<String> keys = formular_fields_map.keySet().iterator();
        while (keys.hasNext())
        {
          key = (String)keys.next();
          list = (List)formular_fields_map.get(key);
          if ((list != null) && (list.size() > 0)) {
            index = getFieldErrorMsgByErrorType(allErrorMsg, list, index, key + NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000000"));
          }
        }
      }
      if (index > 1) {
        throw new LfwRuntimeException(allErrorMsg.toString());
      }
    }
  }
  
  private int getFieldErrorMsgByErrorType(StringBuffer allErrorMsg, List<Field> list, int index, String titleError)
  {
    index++;
    allErrorMsg.append(titleError);
    int size = list.size();
    boolean temp = false;
    for (int i = 0; i < size; i++)
    {
      Field f = (Field)list.get(i);
      allErrorMsg.append((temp ? NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000001") : "") + NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000002") + LanguageUtil.translate(f.getI18nName(), f.getText(), f.getLangDir()) + NCLangRes4VoTransl.getNCLangRes().getStrByID("bc", "DefaultDataValidator-000003"));
      temp = true;
    }
    return index;
  }
  
  private Map<String, Object> validator(Dataset ds)
  {
    return validator(ds, false);
  }
  
  private Map<String, Object> validator(Dataset ds, boolean isAllRow)
  {
    Map<String, Object> validatorMap = new HashMap();
    RowData rd = ds.getCurrentRowData();
    if (rd == null) {
      return null;
    }
    Row[] rows = null;
    if (isAllRow) {
      rows = ds.getAllRow();
    } else {
      rows = getValidatorRows(ds);
    }
    if ((rows == null) || (rows.length == 0)) {
      return null;
    }
    FieldSet fs = ds.getFieldSet();
    int count = fs.getFieldCount();
    if (count == 0) {
      return null;
    }
    Map<String, Integer> errorTypeMap = new LinkedHashMap();
    

    HashMap<String, String> validateFormulaMap = new HashMap();
    

    Map<String, Field> multiMap = new HashMap();
    LfwLanguageVO[] lanVos = LanguageUtil.getEnableLangVOs();
    if ((lanVos != null) && (lanVos.length > 0)) {
      for (int i = 0; i < count; i++) {
        if ((fs.getField(i).getExtendAttribute("Multi") != null) && (58 == ((Integer)fs.getField(i).getExtendAttribute("Multi").getValue()).intValue()))
        {
          multiMap.put(fs.getField(i).getId(), fs.getField(i));
          for (LfwLanguageVO vo : lanVos) {
            multiMap.put(fs.getField(i).getId() + vo.getLangseq(), fs.getField(fs.getField(i).getId() + vo.getLangseq()));
          }
        }
      }
    }
    for (int j = 0; j < rows.length; j++)
    {
      Row row = rows[j];
      int rowIndex = ds.getRowIndex(row);
      if ((rowIndex != -1) && (!(row instanceof EmptyRow))) {
        for (int k = 0; k < count; k++)
        {
          Field field = fs.getField(k);
          String fieldId = field.getId();
          
          boolean isCurrLangField = false;
          if (((field.getExtendAttribute("Multi") != null) && (58 == ((Integer)field.getExtendAttribute("Multi").getValue()).intValue())) || 
          








            (!multiMap.containsKey(fieldId)))
          {
            String value = null;
            if (row.getValue(k) != null)
            {
              value = String.valueOf(row.getValue(k));
              value = value.trim();
            }
            if (isCurrLangField) {
              fieldId = fieldId.substring(0, fieldId.lastIndexOf(String.valueOf(MultiLangContext.getInstance().getCurrentLangSeq())));
            }
            if (!field.isPrimaryKey()) {
              if (field.getSourceField() != null)
              {
                if (errorTypeMap.get(field.getSourceField() + "_" + rowIndex) != null)
                {
                  errorTypeMap.put(fieldId + "_" + rowIndex, errorTypeMap.get(field.getSourceField() + "_" + rowIndex));
                }
                else
                {
                  field = fs.getField(field.getSourceField());
                  int index = fs.fieldToIndexById(field.getId());
                  value = (row.getValue(index) instanceof String) ? (String)row.getValue(index) : null;
                  int type = FieldValidator.validtor(fs.getField(fieldId), value);
                  if (type != -1) {
                    errorTypeMap.put(fieldId + "_" + rowIndex, Integer.valueOf(type));
                  }
                }
              }
              else
              {
                int type = FieldValidator.validtor(fs.getField(fieldId), value);
                if (type != -1) {
                  errorTypeMap.put(fieldId + "_" + rowIndex, Integer.valueOf(type));
                }
              }
            }
            if (errorTypeMap.get(fieldId + "_" + rowIndex) == null)
            {
              String validateFormularStr = field.getValidateFormula();
              if (!StringUtils.isBlank(validateFormularStr)) {
                validateFormulaMap.put(field.getId(), validateFormularStr);
              }
            }
          }
        }
      }
    }
    Map<String, Map<String, String>> formularMsgMap = null;
    try
    {
      formularMsgMap = doProcessValidateFormula(validateFormulaMap, ds);
    }
    catch (Exception e)
    {
      LfwLogger.error(e);
      formularMsgMap = new HashMap(3);
    }
    validatorMap.put("errorTypeMap", errorTypeMap);
    validatorMap.put("formularMsgMap", formularMsgMap);
    return validatorMap;
  }
  
  private Map<String, Map<String, String>> doProcessValidateFormula(HashMap<String, String> validateFormulaMap, Dataset ds)
  {
    Map<String, Map<String, String>> formularMsgMaps = new HashMap(3);
    
    Map<String, String> formularErrorMsgMap = new HashMap();
    Map<String, String> formularMessageMsgMap = new HashMap(10);
    Map<String, String> formularConfirmMsgMap = new HashMap(10);
    formularMsgMaps.put("$Error", formularErrorMsgMap);
    formularMsgMaps.put("$Message", formularMessageMsgMap);
    formularMsgMaps.put("$Confirm", formularConfirmMsgMap);
    
    FormulaParse fp = LfwFormulaParser.getInstance();
    
    List<String> executedFpList = new ArrayList();
    Iterator<String> itor = validateFormulaMap.keySet().iterator();
    while (itor.hasNext())
    {
      String validateFieldKey = (String)itor.next();
      
      String exp = (String)validateFormulaMap.get(validateFieldKey);
      if ((!StringUtils.isBlank(exp)) && 
      
        (!executedFpList.contains(exp)))
      {
        executedFpList.add(exp);
        
        LfwFormulaParser.addExpr(exp, fp);
        VarryVO[] varryVOs = fp.getVarryArray();
        

        int rcount = 0;
        RowData rd = ds.getCurrentRowData();
        if (rd != null) {
          rcount = rd.getRowCount();
        }
        Object[][] result = (Object[][])null;
        if ((varryVOs != null) && (varryVOs.length > 0))
        {
          String[] formularNames = new String[varryVOs.length];
          
          Map<String, Integer> indexMap = getIndexMap(ds);
          for (int j = 0; j < varryVOs.length; j++)
          {
            String[] keys = varryVOs[j].getVarry();
            if (keys != null)
            {
              for (String key : keys)
              {
                List<Object> valueList = new ArrayList();
                for (int k = 0; k < rcount; k++)
                {
                  Row r = rd.getRow(k);
                  if (indexMap.get(key) != null)
                  {
                    Field field = ds.getFieldSet().getField(validateFieldKey);
                    Object value = r.getValue(((Integer)indexMap.get(key)).intValue());
                    if (field.getExtendAttribute(field.getId()) != null)
                    {
                      String refKey = ((Field)field.getExtendAttributeValue(field.getId())).getId();
                      value = r.getValue(((Integer)indexMap.get(refKey)).intValue());
                    }
                    Field f = ds.getFieldSet().getField(key);
                    if ((f != null) && (value != null)) {
                      if (("UFDouble".equals(f.getDataType())) || ("Double".equals(f.getDataType())) || ("Decimal".equals(f.getDataType())) || (("SelfDefine".equals(f.getDataType())) && (f.getPrecision() != null) && (!f.getPrecision().equals(""))))
                      {
                        if (!(value instanceof UFDouble)) {
                          value = new UFDouble(value.toString());
                        }
                      }
                      else if (("Integer".equals(f.getDataType())) && 
                        (!(value instanceof Integer))) {
                        value = new Integer((String)value);
                      }
                    }
                    valueList.add(value);
                  }
                }
                fp.addVariable(key, valueList);
              }
              formularNames[j] = varryVOs[j].getFormulaName();
            }
          }
          result = fp.getValueOArray();
          if (result != null) {
            for (int l = 0; l < formularNames.length; l++)
            {
              int index = ds.nameToIndex(validateFieldKey);
              if (index == -1) {
                LfwLogger.error("can not find var : " + validateFieldKey + ", ds id : " + ds.getId() + ".");
              } else {
                for (int k = 0; k < rcount; k++)
                {
                  Object formulaResult = result[l][k];
                  String errorMessage = String.valueOf(formulaResult);
                  if (!StringUtils.isBlank(errorMessage))
                  {
                    String formularName = formularNames[l];
                    if ("$Confirm".equals(formularName.trim())) {
                      formularConfirmMsgMap.put(validateFieldKey + "_" + k, errorMessage);
                    } else if ("$Message".equals(formularName.trim())) {
                      formularMessageMsgMap.put(validateFieldKey + "_" + k, errorMessage);
                    } else {
                      LfwValidateException.putFormElementToMap(formularErrorMsgMap, validateFieldKey + "_" + k, errorMessage);
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
    return formularMsgMaps;
  }
  
  private Map<String, Integer> getIndexMap(Dataset ds)
  {
    Map<String, Integer> indexMap = new HashMap();
    int count = ds.getFieldSet().getFieldCount();
    for (int i = 0; i < count; i++)
    {
      Field field = ds.getFieldSet().getField(i);
      String key = field.getId();
      indexMap.put(key, Integer.valueOf(i));
    }
    return indexMap;
  }
  
  private Map<String, Object> dealValidator(Map<String, Object> validatorMap, Dataset ds)
  {
    Map<String, Integer> errorTypeMap = (HashMap)validatorMap.get("errorTypeMap");
    
    Map<String, Map<String, String>> formularMsgMaps = (Map)validatorMap.get("formularMsgMap");
    Map<String, String> formularMsgMap = (Map)formularMsgMaps.get("$Error");
    if (((errorTypeMap != null) && (!errorTypeMap.isEmpty())) || ((formularMsgMap != null) && (!formularMsgMap.isEmpty())))
    {
      FieldSet fs = ds.getFieldSet();
      
      Map<String, String> error_fields_map = new HashMap();
      
      Map<Integer, List<Field>> type_fields_map = null;
      if (!errorTypeMap.isEmpty())
      {
        type_fields_map = new HashMap();
        List<Field> list = null;
        String key = null;
        String fieldId = null;
        Iterator<String> keys = errorTypeMap.keySet().iterator();
        while (keys.hasNext())
        {
          key = (String)keys.next();
          fieldId = key.substring(0, key.lastIndexOf("_"));
          
          list = (List)type_fields_map.get(errorTypeMap.get(key));
          if (list == null) {
            list = new ArrayList();
          }
          boolean temp = true;
          if (fs.getField(fieldId).getSourceField() != null) {
            for (Field f : list) {
              if (f.getId().equals(fs.getField(fieldId).getSourceField()))
              {
                list.remove(f);
                break;
              }
            }
          } else {
            for (Field f : list) {
              if (fs.getField(fieldId).getId().equals(f.getSourceField()))
              {
                temp = false;
                break;
              }
            }
          }
          if (temp)
          {
            list.add(fs.getField(fieldId));
            type_fields_map.put(errorTypeMap.get(key), list);
          }
          error_fields_map.put(key, FieldValidator.getValidatorMsg(((Integer)errorTypeMap.get(key)).intValue()));
        }
      }
      Map<String, List<Field>> formular_fields_map = null;
      if (!formularMsgMap.isEmpty())
      {
        formular_fields_map = new HashMap();
        List<Field> list = null;
        String key = null;
        String fieldId = null;
        Iterator<String> keys = formularMsgMap.keySet().iterator();
        while (keys.hasNext())
        {
          key = (String)keys.next();
          fieldId = key.substring(0, key.lastIndexOf("_"));
          list = (List)formular_fields_map.get(formularMsgMap.get(key));
          if (list == null) {
            list = new ArrayList();
          }
          boolean temp = true;
          if (fs.getField(fieldId).getSourceField() != null) {
            for (Field f : list) {
              if (f.getId().equals(fs.getField(fieldId).getSourceField()))
              {
                list.remove(f);
                break;
              }
            }
          } else {
            for (Field f : list) {
              if (fs.getField(fieldId).getId().equals(f.getSourceField()))
              {
                temp = false;
                break;
              }
            }
          }
          if (temp)
          {
            list.add(fs.getField(fieldId));
            formular_fields_map.put(formularMsgMap.get(key), list);
          }
        }
        error_fields_map.putAll(formularMsgMap);
      }
      validatorMap.put("type_fields_map", type_fields_map);
      
      validatorMap.put("formular_fields_map", formular_fields_map);
      
      validatorMap.put("error_fields_map", error_fields_map);
    }
    Map<String, String> formularMessageMap = (Map)formularMsgMaps.get("$Message");
    if ((formularMessageMap != null) && (!formularMessageMap.isEmpty())) {
      validatorMap.put("$Message", formularMessageMap);
    }
    Map<String, String> formularConfirmMap = (Map)formularMsgMaps.get("$Confirm");
    if ((formularConfirmMap != null) && (!formularConfirmMap.isEmpty())) {
      validatorMap.put("$Confirm", formularConfirmMap);
    }
    return validatorMap;
  }
  
  public Row[] getValidatorRows(Dataset ds)
  {
    if (ds.getAllChangedRows().length > 0) {
      return ds.getAllChangedRows();
    }
    return ds.getAllSelectedRows();
  }
}
